

package com.fjb.controller.plugins;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections4.map.HashedMap;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.ExistsBuilder;
import org.apache.curator.framework.api.GetACLBuilder;
import org.apache.curator.framework.api.GetConfigBuilder;
import org.apache.curator.framework.imps.CuratorFrameworkState;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.fjb.common.entity.HttpCode;
import com.fjb.common.entity.JsonResult;
import com.fjb.common.entity.JsonTotalResult;
import com.fjb.config.plugins.ZkTreeNode;
import com.fjb.controller.base.BaseController;

/**
 * @Description:zooKeeper
 * @author hemiao
 * @time:2020年3月6日 下午1:18:24
 */
@Controller
@RequestMapping("/pluginsZk")
public class ZkController extends BaseController{
	
	private static final Logger logger = LoggerFactory.getLogger(ZkController.class);
	
	/**
	 * 节点分隔符
	 */
	public static final String SEPARATOR = "/"; 
	
	private static String connectString = "127.0.0.1:2181";
	
	private CuratorFramework cfClient;
	
	public CuratorFramework getCuratorClient() {
		if(cfClient==null) {
			RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
			cfClient = CuratorFrameworkFactory.newClient(connectString, retryPolicy);
			cfClient.start();	
			logger.info(" cfClient start 启动连接成功");
			return cfClient;
		}		
		return cfClient;
	}

	public void setCuratorClient(CuratorFramework cfClient) {
		this.cfClient = cfClient;
	}

	/**
	 * @Description:显示zk页面
	 * @param request
	 * @return
	 * ModelAndView
	 * @exception:
	 * @author: hemiao
	 * @time:2020年3月6日 下午1:20:56
	 */
	@RequestMapping(value="/showZkIndex")
	public ModelAndView showZkIndex(HttpServletRequest request) {
		ModelAndView mv = new ModelAndView();
		
		mv.setViewName("/plugins/zk_index");
		return mv;
	}
	
	/**
	 * @Description:zk 连接
	 * @param request
	 * @return
	 * JsonResult<List<Object>>
	 * @exception:
	 * @author: hemiao
	 * @time:2020年3月6日 下午4:56:05
	 */
	@RequestMapping(value="/connect")
	@ResponseBody
	public JsonResult<Object> connect(HttpServletRequest request){
		HttpCode httpCode = HttpCode.PARAM_VERIFICATION;
		
		CuratorFramework client = getCuratorClient();
		//RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
		//CuratorFramework client = CuratorFrameworkFactory.newClient(connectString, retryPolicy);	
//		CuratorFramework client = CuratorFrameworkFactory.builder().connectString(connectString).sessionTimeoutMs(Integer.valueOf(10000)).
//				retryPolicy(retryPolicy).build();
		//client.start();
		
		CuratorFrameworkState state = client.getState();
		HashedMap<String, Object> resultMap = new HashedMap<String,Object>();
		resultMap.put("zkState", state);	
		return new JsonResult<Object>(resultMap, HttpCode.SUCCESS);
	}
	
	/**
	 * @Description:zk 关闭
	 * @param request
	 * @return
	 * JsonResult<List<Object>>
	 * @exception:
	 * @author: hemiao
	 * @time:2020年3月6日 下午4:55:55
	 */
	@RequestMapping(value="/close")
	@ResponseBody
	public JsonResult<Object> close(HttpServletRequest request){
		CuratorFramework client = getCuratorClient();
		client.close();		
		setCuratorClient(null);
		CuratorFrameworkState state = client.getState();
		HashedMap<String, Object> resultMap = new HashedMap<String,Object>();
		resultMap.put("zkState", state);			
		return new JsonResult<Object>(resultMap, HttpCode.SUCCESS);
	}
	
	// 获得zk 状态  
	@RequestMapping(value="/status")
	@ResponseBody
	public JsonResult<Object> status(HttpServletRequest request){
		CuratorFramework client = getCuratorClient();
		CuratorFrameworkState state = client.getState();
		HashedMap<String, Object> resultMap = new HashedMap<String,Object>();
		resultMap.put("zkState", state);			
		return new JsonResult<Object>(resultMap, HttpCode.SUCCESS);
	}
	
	/**
	 * @Description: 获得zj所有的节点
	 * @param request
	 * @return
	 * @throws Exception
	 * JsonResult<Object>
	 * @exception:
	 * @author: hemiao
	 * @time:2020年3月6日 下午4:55:43
	 */
	@RequestMapping(value="/getAllNodes")
	@ResponseBody
	public JsonResult<Object> getAllNodes(HttpServletRequest request) throws Exception{
		CuratorFramework cfClient = getCuratorClient();
		/*List<String> forPath = new ArrayList<String>();
		try {		
			//forPath = cfClient.getChildren().forPath(SEPARATOR);
			forPath = getRecursionNodeList(cfClient, SEPARATOR);
		} catch (Exception e1) {
			e1.printStackTrace();
		}*/
		List<ZkTreeNode> zkNodeList = getRecursionNodeList(cfClient, SEPARATOR);
		/*if(forPath.size()>0) {
			for (String path : forPath) {
				ZkTreeNode treeNode = new ZkTreeNode();
				treeNode.setId(path);
				treeNode.setpId(SEPARATOR);
				treeNode.setName(path);
				zkNodeList.add(treeNode);
			}
		}*/
		return new JsonResult<Object>(zkNodeList, HttpCode.SUCCESS);
	}
	
	@RequestMapping(value="/getData")
	@ResponseBody
	public JsonTotalResult<Object> getData(HttpServletRequest request) throws Exception{
		// 节点路径
		String path = request.getParameter("path");
		// 节点名称
		String psthName = request.getParameter("psthName");
		
		CuratorFramework cfClient = getCuratorClient();
		List<Object> resultList = new ArrayList<Object>();
		
		String dataStr1 = "";	
		byte[] data1 = null;	
		data1 = cfClient.getData().forPath(path);
		if(data1!=null) {
			dataStr1 = new String(data1);
		}	
		Stat nodeStat1 = cfClient.checkExists().forPath(path);
		HashedMap<String,Object> hashedMap1 = new HashedMap<String,Object>();
		hashedMap1.put("nodeName", psthName);				
		hashedMap1.put("nodeData", dataStr1);			
		hashedMap1.put("nodeStat", nodeStat1);	
		hashedMap1.put("path", path);	
		resultList.add(hashedMap1);				
		// 获得这个 节点下节点	
		List<String> forPath = cfClient.getChildren().forPath(path);
		if(forPath.size()>0) {
			for (String str : forPath) {
				String dataStr = "";	
				byte[] data = null;	
				data = cfClient.getData().forPath(path+SEPARATOR+str);
				if(data!=null) {
					dataStr = new String(data);
				}	
				Stat nodeStat = cfClient.checkExists().forPath(path+SEPARATOR+str);
				HashedMap<String,Object> hashedMap = new HashedMap<String,Object>();
				hashedMap.put("nodeName", str);			
				hashedMap.put("nodeData", dataStr);		
				hashedMap.put("nodeStat", nodeStat);		
				hashedMap.put("path", path+SEPARATOR+str);
				resultList.add(hashedMap);	
			}	
		}
		return new JsonTotalResult<Object>(resultList, HttpCode.SUCCESS, Long.valueOf(1));
	}
	
	/**
	 * @Description:获得子节点
	 * @param request
	 * @return
	 * @throws Exception
	 * JsonResult<Object>
	 * @exception:
	 * @author: hemiao
	 * @time:2020年3月6日 下午4:56:17
	 */
	@RequestMapping(value="/getChildrenNode")
	@ResponseBody
	public JsonResult<Object> getChildrenNode(HttpServletRequest request) throws Exception{
		
		return new JsonResult<Object>(null, HttpCode.SUCCESS);
	}
	
	// 获得 zk的状态
	@RequestMapping(value="/getState")
	@ResponseBody
	public JsonResult<Object> getState(HttpServletRequest request) throws Exception{
		
		return new JsonResult<Object>(null, HttpCode.SUCCESS);
	}
	
	// zk create
	@RequestMapping(value="/create")
	@ResponseBody
	public JsonResult<Object> create(HttpServletRequest request) throws Exception{
		
		
		
		return new JsonResult<Object>(null, HttpCode.SUCCESS);
	}
	
	
	public static void main(String[] args) throws InterruptedException {
		
		String connectString = "127.0.0.1:2181";
		RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
		CuratorFramework cfClient = CuratorFrameworkFactory.newClient(connectString, retryPolicy);
		cfClient.start();
		
		List<ZkTreeNode> nodeList = getRecursionNodeList(cfClient, "/");
		System.out.println(JSON.toJSON(nodeList));
	   
        cfClient.close();	
        CuratorFrameworkState state2 = cfClient.getState();
		System.out.println("end state "+JSON.toJSONString(state2));
    }
	
	// 递归获得节点
	public static List<ZkTreeNode> getRecursionNodeList(CuratorFramework cfClient,String node){
		List<String> forPath = new ArrayList<String>();
		try {		
			forPath = cfClient.getChildren().forPath(node);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		List<ZkTreeNode> zkNodeList = new ArrayList<ZkTreeNode>();
		if(forPath.size()>0) {
			for (String path : forPath) {	
				StringBuffer sb = new StringBuffer();
				if(node.equals(SEPARATOR)) {
					String strNode = sb.append(SEPARATOR).append(path).toString();
					ZkTreeNode treeNode = new ZkTreeNode();
					treeNode.setId(strNode);	
					treeNode.setpId(node);
					treeNode.setName(path);	
					zkNodeList.add(treeNode);
					List<ZkTreeNode> nodeList = getRecursionNodeList(cfClient, strNode);
					zkNodeList.addAll(nodeList);
				}else {	
					String strNode = sb.append(node).append(SEPARATOR).append(path).toString();
					ZkTreeNode treeNode = new ZkTreeNode();
					treeNode.setId(strNode);
					treeNode.setpId(node);
					treeNode.setName(path);	
					zkNodeList.add(treeNode);
					List<ZkTreeNode> nodeList = getRecursionNodeList(cfClient, strNode);
					zkNodeList.addAll(nodeList);
				}
			}
		}
		return zkNodeList;
	}
}
